package org.groupg.practice.data._1000wData;


import org.groupg.practice.data.DataRecord;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 使用内存映射文件处理超大数据集
 * 可以处理远超堆内存大小的数据
 */
public class MemoryMappedDataStore {
    private static final int RECORD_SIZE = 4 + 8 + 8 + 32; // id + timestamp + value + label
    private final String filePath;
    private MappedByteBuffer buffer;
    private int recordCount;

    public MemoryMappedDataStore(String filePath, int maxRecords) throws IOException {
        this.filePath = filePath;

        RandomAccessFile file = new RandomAccessFile(filePath, "rw");
        long fileSize = (long) maxRecords * RECORD_SIZE;

        // 创建内存映射
        this.buffer = file.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, fileSize);
        file.close();
    }

    /**
     * 写入记录到内存映射区域
     */
    public void writeRecord(int index, int id, long timestamp, double value, String label) {
        int position = index * RECORD_SIZE;

        buffer.putInt(position, id);
        buffer.putLong(position + 4, timestamp);
        buffer.putDouble(position + 12, value);

        // 字符串处理（简化版）
        byte[] labelBytes = label.getBytes(java.nio.charset.StandardCharsets.UTF_8);
        int labelLength = Math.min(labelBytes.length, 32);
        buffer.put(position + 20, (byte) labelLength);
        for (int i = 0; i < labelLength; i++) {
            buffer.put(position + 21 + i, labelBytes[i]);
        }

        recordCount = Math.max(recordCount, index + 1);
    }

    /**
     * 从内存映射区域读取记录
     */
    public DataRecord readRecord(int index) {
        int position = index * RECORD_SIZE;

        int id = buffer.getInt(position);
        long timestamp = buffer.getLong(position + 4);
        double value = buffer.getDouble(position + 12);

        int labelLength = buffer.get(position + 20);
        byte[] labelBytes = new byte[labelLength];
        for (int i = 0; i < labelLength; i++) {
            labelBytes[i] = buffer.get(position + 21 + i);
        }
        String label = new String(labelBytes, java.nio.charset.StandardCharsets.UTF_8);

        return new DataRecord(id, timestamp, value, label);
    }

    public int size() {
        return recordCount;
    }
}